/*
模拟new操作符
1.创建一个具有被new函数原型对象的对象
2.改变this指向
3.如果该函数返回值为object或者function,就将其返回,如果没有就返回构建的对象
*/
// function _new(Func,...args) {
//     let obj = Object.create(Func.prototype)
//     let res = Func.call(obj,...args)
//     //如果函数执行完后的返回值是一个对象或者函数,就将其返回
//     if(res!=null&&/^(object|function)$/.test(typeof res))  return res
//     return obj
// }


// function Person(names){
//     this.name = names
//     return {name:'wang'}
// }
// Person.prototype.say=function() {
//     console.log('i can say :',this.name)
// }

// const p = _new(Person,'liang')
// console.log(p.name)
// p.say()
// ------------------------------------------------------------------------------------------------------------------------------
/*
模拟call方法
1.判断传入的上下文,如果是null或者undefined,就指向window.如果不是对象或者函数,就用Object()进行包装
2.使用Symbol创建一个独一无二的值,作为传入上下文的一个属性,并将当前的this(调用call的函数)指向他
3.通过当前上下文的这个属性,进行函数的调用,
4.删除上下文的这个属性
5.如果之前的函数调用有返回值,就return这个结果
*/
// (proto=>{
//     function myCall(context,...args) {
//         context = context == undefined||null?window:context
//         if(!/^(object|function)$/.test(typeof context)) {
//            context =  Object(context)
//         }
//         let key = Symbol('key')
//         context[key] = this
//         let res = context[key](...args)
//         delete context[key]
//         return res
//     }
//     proto.myCall = myCall

// })(Function.prototype)

// function test(name) {
//     console.log('i am here :',name)
// }

// const obj ={
//     name:'liang'
// }

// test.myCall(obj,'helloworld')

//将一个基本数据类型转换为object类型
// let str = 2
// let obj = new str.constructor(str)

// console.log( typeof obj);  //object

// -------------------------------------------------------------------------------------------------------------------------
/*
节流
*/
// function throttle(foo,delay) {
//     let timer = null
//     let turn = true
//     return function() {
//         if(!turn) {
//             clearInterval(timer)
//         }
//         turn = false
//         timer = setTimeout(function() {
//             turn = true
//             foo()
//         },delay)
//     }
// }

// let one = new Date
// setTimeout(()=> console.log(new Date - one),1000) 

//js手写new
// function _new(Func,...args) {
//     let obj = Object.create(Func.prototype)
//     let res = Func.call(obj,...args)
//     if(res!=null&&/^(object|function)$/.test(typeof res)) return res
//     return obj
// }

// function Person(names) {
//     this.names = names
// }
// Person.prototype.say = function() {
//     console.log(` i can say: ${this.names} `)
// }

// let student = _new(Person,'hello world')
// student.say()

//手写map
let arr = [1, 2, 3, 4, 5]
// arr.map(item => item*2)
// arr.map(function(item) {
//     return item*2
// })


// function map(fn) {
//     let newArr = null
//     for(let i = 0;i<this.length;i++) {
//        newArr.push(fn(this[i])) 
//     }
//     return newArr
// }

// let aaa = arr.map(function(item) {
//     return item*2
// })

// console.dir(aaa)

//手写filter
let a = 9
console.log(Object.prototype.toString.call(a))  //object Number